
''' <summary>
''' BikiRom Variable Holder class (internal use only)
''' </summary>
''' <remarks></remarks>
<Serializable()> Friend Class BVars
    Private m_description As BikDescription = Nothing
    Private m_name As String = ""
    Private m_firstNode As BVar = Nothing

    Friend Sub New(ByVal Name As String)
        m_name = Name
    End Sub
    Friend Sub addNode(ByRef Var_ As BVar)
        If Not IsNothing(Var_) Then
            If IsNothing(m_firstNode) Then
                m_firstNode = Var_
            Else
                If LCase(m_firstNode.Name) <> LCase(Var_.Name) Or LCase(Var_.Name) = "note" Then
                    m_firstNode.addNode(Var_)
                End If
            End If
        End If
    End Sub
    Friend Function count() As Integer
        Dim intReturn As Integer = 0
        If Not IsNothing(m_firstNode) Then
            intReturn = m_firstNode.count
        End If
        Return intReturn
    End Function

    Public Property Description() As BikDescription
        Get
            Return m_description
        End Get
        Set(ByVal value As BikDescription)
            m_description = value
        End Set
    End Property
    Public Property Name_() As String
        Get
            Return m_name
        End Get
        Set(ByVal value As String)
            m_name = value
        End Set
    End Property
    Friend Function getFirst() As BVar
        If IsNothing(m_firstNode) Then
            Return Nothing
        Else
            Return m_firstNode
        End If
    End Function

    Friend Function getByName(ByVal Name_ As String) As BVar
        Dim f_cursor As BVar
        Dim found As Boolean = False
        Name_ = LCase(Name_)
        If Not IsNothing(m_firstNode) Then
            f_cursor = m_firstNode
            If LCase(f_cursor.Name) = Name_ Then
                found = True
                GoTo endMod
            End If
            While Not found
                If Not IsNothing(f_cursor.getnext) Then
                    f_cursor = f_cursor.getnext
                    If LCase(f_cursor.Name) = Name_ Then
                        found = True
                        GoTo endMod
                    End If
                Else
                    found = False
                    GoTo endMod
                End If
            End While
        Else
            Return Nothing
        End If
endMod:
        If found Then Return f_cursor Else Return Nothing
    End Function
    Friend Function getByIndex(ByVal Index_ As Integer) As BVar
        Dim f_cursor As BVar
        Dim found As Boolean = False
        If Not IsNothing(m_firstNode) Then
            f_cursor = m_firstNode
            If Index_ = 0 Then
                Return f_cursor
                found = True
            Else
                For count As Integer = 1 To Index_
                    If Not IsNothing(f_cursor.getnext) Then
                        f_cursor = f_cursor.getnext
                        found = True
                    Else
                        Return Nothing
                        Exit For
                    End If
                Next
            End If
        Else
            Return Nothing
        End If
        If found = False Then Return Nothing Else Return f_cursor
    End Function
    Friend Function getAsArray(Optional ByVal key As String = "") As BVar()
        Dim f_count As Integer
        Dim f_final As Integer
        Dim f_varArray() As BVar = Nothing
        If Not IsNothing(m_firstNode) Then
            f_count = m_firstNode.count
            ReDim f_varArray(0 To f_count - 1)
            For i As Integer = 0 To f_count - 1
                If Me.getByIndex(i).getKey = key Or key = "" Then
                    f_varArray(f_final) = Me.getByIndex(i)
                    f_final += 1
                End If
            Next
            ReDim Preserve f_varArray(f_final - 1)
        End If
        Return f_varArray
    End Function
    Friend Function getCRC() As UShort
        Dim ol As UShort = 0
        For Each var As BVar In Me.getAsArray
            For Each by As Byte In cv_BytesFromString(var.Description.Description)
                crc(by, ol)
            Next
            For Each by As Byte In cv_BytesFromString(var.Name)
                crc(by, ol)
            Next
            crc(CByte(var.Value And &HFF), ol)
            crc(CByte((var.Value And &HFF00) >> 8), ol)
            crc(CByte((var.Value And &HFF0000) >> 16), ol)
            crc(CByte((var.Value And &HFF000000) >> 24), ol)
        Next
        Return ol
    End Function

    Friend Function removeByIndex(ByVal Index_ As Integer) As Boolean
        Dim ret As Boolean = False
        Dim f_map As BVar = Me.getByIndex(Index_)
        If Not IsNothing(f_map) Then
            Me.removeByName(f_map.Name)
            ret = True
        End If
        Return ret
    End Function
    Friend Function removeByName(ByVal Name_ As String) As Boolean
        Dim s_first As BVar
        Dim s_temp As BVar
        Dim found As Boolean = False


        If Not IsNothing(m_firstNode) Then
            If LCase(m_firstNode.Name) = LCase(Name_) Then
                If IsNothing(m_firstNode.getnext) Then
                    m_firstNode = Nothing
                Else
                    s_temp = m_firstNode.getnext
                    m_firstNode = Nothing
                    Me.addNode(s_temp)
                End If
            Else
                ' First node not a match.. now check all other nodes
                s_first = m_firstNode
                Do
                    If LCase(s_first.getnext.Name) = LCase(Name_) Then
                        'next node is a match..
                        If IsNothing(s_first.getnext.getnext) Then
                            'next node has no next.. so just null delete the link
                            s_first.setNext(Nothing)
                            found = True
                            GoTo endSub
                        Else
                            'the next node has a next.. so must swap the links
                            s_temp = s_first.getnext.getnext
                            s_first.setNext(s_temp)
                            found = True
                            GoTo endSub
                        End If
                    End If
                    s_first = s_first.getnext
                Loop Until found Or IsNothing(s_first.getnext)
            End If
        End If
endSub:
        s_first = Nothing
        s_temp = Nothing
        If found Then Return True Else Return False
    End Function
End Class
